import { Component, OnInit, EventEmitter } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { Observable } from "rxjs/Observable";
import { ConnectableObservable } from "rxjs/Observable/ConnectableObservable";
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { distinctUntilChanged } from 'rxjs/operator/distinctUntilChanged';

import { TableTab, TableHeader } from "../f10-shared/interface-shared";
import { scroll } from "../f10-shared/common-methods";
import { removeHMS, compare, basicChartColors, optimizeUnit } from "../f10-shared/util";
import { F10Service } from "../service/f10.service";
import { ScrollService } from "../service/scroll.service";
import { AssetsHeader,
  IncomeHeader,
  CashflowHeader,
  PerfforecastHeader,
  ProfitHeader,
  DevelopHeader,
  ManageHeader,
  CashflowAanasisHeader,
  SolvencyHeader,
  CapitalStructureHeader
} from "./tableHeader-json";
import cloneDeep from "lodash/fp/cloneDeep";

interface HeaderDict {
  profit: TableHeader[],
  develop: TableHeader[],
  manage: TableHeader[],
  cashflow: TableHeader[],
  solvency: TableHeader[],
  stockIndicator: TableHeader[],
}

let config = {
  type: 'line',
  data: {
    labels: [],
    datasets: []
  },
  options: {
    responsive: true,
    maintainAspectRatio: false,
    // spanGaps: true, // 中间缺点的时候是否需要忽略该点平滑连接
    elements: {
      line: {
        tension: 0.000001
      }
    },
    title:{
      display:true,
      text: '',
      padding: 7
    },
    tooltips: {
      mode: 'index',
      intersect: false,
      callbacks: {
        // use the label callback to change label
        label: (tooltipItems, data, all) => {
          let labelVal = optimizeUnit(Math.abs(tooltipItems.yLabel))
          let labelTitle = data.datasets[tooltipItems.datasetIndex].label
          return !isNaN(parseFloat(labelVal)) && parseFloat(labelVal) !== 0
            ? tooltipItems.yLabel > 0
              ? `${labelTitle}: ${labelVal}`
              : `${labelTitle}: -${labelVal}`
            : `${labelTitle}: --`
          return 
        }
      }
    },  
    hover: {
      mode: 'nearest',
      intersect: true
    },
    scales: {
      xAxes: [{
        display: true,
        scaleLabel: {
          display: false,
          labelString: 'Month'
        }
      }],
      yAxes: [{
        ticks: {
          callback: (label, index, all) => {
            let newVal = (all[0] - all[all.length - 1]) > 5 ? Math.round(Math.abs(label)) : Math.abs(label).toFixed(2)
            let labelVal = optimizeUnit(newVal)
            return label >= 0
              ? labelVal
              : `-${labelVal}`
          }
        }
      }]
    }
  }
}

@Component({
  templateUrl: 'finance.component.html',
  styleUrls: ['finance.component.less']
})
export class FinanceComponent implements OnInit {
  timer = null;
  tabClicked = {
    flag: false
  };
  activeTabIndex = 0;
  scrollTimer = null;
  mustChange = false;
  subLists: TableTab[] = [
    {
      label: "财务透视",
      class: 'sub-title-0'
    },
    {
      label: "财务分析",
      class: 'sub-title-1'
    },
    // {
    //   label: "杜邦分析",
    //   class: 'sub-title-2'
    // },
    // {
    //   label: "财务报告",
    //   class: 'sub-title-3'
    // },
    {
      label: "业绩预告",
      class: 'sub-title-4'
    }
  ]
  // 股票代码Observable
  routerParamsStream: Observable<any>;
  // 三大报表表格数据
  tableData: Observable<any>;
  tableHeader: TableHeader[] = []
  // 财务透视表tab
  financialStatements: TableTab[] = [
    {
      label: '资产负债表',
      class: 'getAssets'
    },
    {
      label: '利润表',
      class: 'getIncome'
    },
    {
      label: '现金流量表',
      class: 'getCashflow'
    }
  ]
  // 资产负债表字段
  assetsHeader: TableHeader[] = AssetsHeader
  // 利润表字段
  incomeHeader: TableHeader[] = IncomeHeader
  // 现金流量表字段
  cashflowHeader: TableHeader[] = CashflowHeader

  // 财务分析
  financialAnalysis: TableTab[] = [
    {
      label: '盈利能力',
      class: 'profit'
    },
    {
      label: '偿债能力',
      class: 'solvency'
    },
    {
      label: '成长能力',
      class: 'develop'
    },
    {
      label: '营运能力',
      class: 'manage'
    },
    {
      label: '现金状况',
      class: 'cashflow'
    },
    {
      label: '资本结构',
      class: 'capitalStructure'
    }
  ]
  abilityTableHeader: TableHeader[] = []

  profitHeader: TableHeader[] = ProfitHeader
  solvencyHeader: TableHeader[] = SolvencyHeader
  developHeader: TableHeader[] = DevelopHeader
  manageHeader: TableHeader[] = ManageHeader
  cashflowAanasisHeader: TableHeader[] = CashflowAanasisHeader
  capitalStructureHeader: TableHeader[] = CapitalStructureHeader

  abilityTableHeaderDict: HeaderDict = {
    profit: this.profitHeader,
    solvency: this.solvencyHeader,
    develop: this.developHeader,
    manage: this.manageHeader,
    cashflow: this.cashflowAanasisHeader,
    capitalStructure: this.capitalStructureHeader,
  }
  
  // 业绩预告
  perfforecastHeader: TableHeader[] = PerfforecastHeader
  perfforecastData: Observable<any>;
  // 手动推流 => observable
  tabEmitter = new BehaviorSubject("getAssets")

  // 图表数据
  perspectiveChartSource: Observable<any>;
  perspectiveChartEmitter = new BehaviorSubject(this.assetsHeader[1]);
  perspectiveClickedKey:string = this.assetsHeader[1].key;
  perspectiveChartTitle:string = this.financialStatements[0].label

  analysisChartSource: Observable<any>;
  analysisChartEmitter = new BehaviorSubject(this.profitHeader[1]);
  analysisClickedKey:string = this.profitHeader[1].key;
  analysisChartTitle:string = this.financialAnalysis[0].label
  constructor(
    private router: ActivatedRoute,
    private f10Service: F10Service,
    private scrollService: ScrollService
  ) { }

  ngOnInit() {
    // 获取股票代码
    this.routerParamsStream = this.router.parent.parent.params.map(params => params["id"]).filter(id => !!id).map(id => {
      let stock = {
        symbol: (<string>id).replace("_", ".")
      };
      return stock
    })

    // 三大报表
    this.tableHeader = this.assetsHeader
    // 财务分析
    this.abilityTableHeader = this.profitHeader
    this.tableData = this.routerParamsStream
      .switchMap((stock) => this.f10Service.getFinacialAnalysis(stock.symbol))
      .map(data =>
        (<any[]>data).map(d =>
          ({
            ...d,
            'EndDate': removeHMS(d['EndDate'])
          })
        ).sort(compare('EndDate', 'des'))
      ).publish().refCount()

    // 透视图表
    this.perspectiveChartSource = this.tableData
      .map(data => [...data].reverse())
      .switchMap(rawData => {
        return this.perspectiveChartEmitter
          .distinctUntilChanged()
          .map(header => {
            let labels = []
            let data = []
            rawData.forEach(d => {
              labels = [...labels, d[this.tableHeader[0].key]];
              data = [...data, parseFloat(d[header.key])]
            })
            return {
              title: header.label,
              labels: labels,
              data: data
            }
          })
      })
      .scan((accu, curr) => {
        accu.data.labels = [...curr.labels];
        accu.data.datasets = [{
          label: curr.title,
          backgroundColor: basicChartColors[0],
          borderColor: basicChartColors[0],
          data: [...curr.data],
          fill: false,
          pointRadius: 5,
          borderJoinStyle: 'round'
        }]
        accu.options.title.text = this.perspectiveChartTitle
        return {...accu}
      }, cloneDeep(config))

    // 财务分析图表
    this.analysisChartSource = this.tableData
      .map(data => [...data].reverse())
      .switchMap(rawData => {
        return this.analysisChartEmitter
          .distinctUntilChanged()
          .map(header => {
            let labels = []
            let data = []
            rawData.forEach(d => {
              labels = [...labels, d[this.abilityTableHeader[0].key]];
              data = [...data, parseFloat(d[header.key])]
            })
            return {
              title: header.label,
              labels: labels,
              data: data
            }
          })
      })
      .scan((accu, curr) => {
        accu.data.labels = [...curr.labels];
        accu.data.datasets = [{
          label: curr.title,
          backgroundColor: basicChartColors[0],
          borderColor: basicChartColors[0],
          data: [...curr.data],
          fill: false,
          pointRadius: 5,
          borderJoinStyle: 'round'
        }]
        accu.options.title.text = this.analysisChartTitle
        return {...accu}
      }, cloneDeep(config))
  
    // 业绩预告
    this.perfforecastData = this.routerParamsStream
      .switchMap(stock => this.getPerfforecast(stock.symbol))
  }

  tabToggle(event) {
    this.timer = scroll(`segment-container`, event, this.timer);
  }

  scrollEvent (e, el, el1, el2, el3, el4, el5) {
    if (this.scrollTimer) clearTimeout(this.scrollTimer)
    this.scrollTimer = setTimeout(() => {
      this.mustChange = !this.mustChange
      this.tabClicked.flag = false
      this.activeTabIndex = this.scrollService.tabIndex(e, el, el1, el2, el3, el4, el5)
    }, 50)
    if (this.tabClicked.flag) return
    this.activeTabIndex = this.scrollService.tabIndex(e, el, el1, el2, el3, el4, el5)
  }

  // 切换报表
  tabelToggle(event) {
    if (event === 'getAssets') {
      this.tableHeader = [...this.assetsHeader]
    } else if (event === 'getIncome') {
      this.tableHeader = [...this.incomeHeader]
    } else if (event === 'getCashflow') {
      this.tableHeader = [...this.cashflowHeader]
    }
    // 更新表格
    this.tabEmitter.next(event)
    // 更新图表
    this.perspectiveChartTitle = this.financialStatements.filter(d => d.class === event)[0].label
    this.perspectiveClickedKey = this.tableHeader[1].key
    this.togglePerspectiveChart(this.tableHeader[1])
  }
  // 切换透视图表数据
  togglePerspectiveChart (payload) {
    this.perspectiveChartEmitter.next(payload)
  }

  // 切换财务分析tab
  abilityToggle(event) {
    // 更新表格
    this.abilityTableHeader = this.abilityTableHeaderDict[event]
    // 更新图表
    this.analysisChartTitle = this.financialAnalysis.filter(d => d.class === event)[0].label
    this.analysisClickedKey = this.abilityTableHeader[1].key
    this.toggleAnalysisChart(this.abilityTableHeader[1])
  }
  // 切换财务分析图表数据
  toggleAnalysisChart (payload) {
    this.analysisChartEmitter.next(payload)
  }

  // 业绩预告
  getPerfforecast (symbol) {
    return this.f10Service.getPerfforecast(symbol)
      .map(data => data.map((d, i) => ({
        ...d,
        infoPublDate: removeHMS(d['infoPublDate']),
        endDate: removeHMS(d['endDate'])
      })).sort(compare('infoPublDate', 'des')))
      .map(data => data.map((d, i) => ({
        ...d,
        $id: i + 1
      })))
  }
}